/**
 * 
 */
package TextEditor;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JSeparator;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JToolBar;
//zcs import
import javax.swing.JComponent;
import javax.swing.InputMap;
import javax.swing.KeyStroke;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

import TextEditor.facade.FileKeeper;



/**
 * Main GUI creation class
 * @author Timur Utepov
 */
public class EditorWindow extends JFrame implements ActionListener, DocumentListener,KeyListener
{
	public static final int WIDTH = 900;
	public static final int HEIGHT = 600;
	public static final int LOCATIONX = 100;
	public static final int LOCATIONY = 50;
	
	private static final int DISCARDFILE = -1;
	private int head = 0;

	
	private JMenuItem recordMacro;
	private JMenuItem stopMacro;
	private JMenuItem playMacro;
	
	//@ZHYJ: the text edit component and status bar in the main interface.
	public JTextArea textArea;
	JLabel infoStatus;
	JToolBar toolBar = new JToolBar();
	JTextField textField = new JTextField();
	
	//@ZHYJ:variants about keep original content original content of texteditor
	private boolean isNewFile = true;
	private boolean isModified = false ;
	private File currentFile = null;
	//jie adding macro object
	private KeyboardMacroProcessor macroItem=new KeyboardMacroProcessor() ;



	/**
	 * Constructor. Encapsulates the creation of all window items
	 */
	public EditorWindow()
	{
		super();
		setWindowParameters();
		createStandardMenu();
		addToolbar();
		addTextArea();
		addStatusBar();
		// add close window listener on upper right cross button
		addWindowListener(new WindowAdapter()
		{	
			public void windowClosing(WindowEvent e)
			{	
				exitWindowAction();
			}
		});
	}

	/**
	 * Sets location, size, and title of main window
	 */
	private void setWindowParameters() {
		setSize(WIDTH, HEIGHT);
		setLocation(LOCATIONX, LOCATIONY);
		setTitle("Collaborative TextEditor. Group 4. SOEN 6441");
		//@ZHYJ: add new window closing 
		setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
	}

	/**
	 * Encapsulates creation of standard static menu items
	 */
	private void createStandardMenu() {
		String[] fileItems = new String[] { "New", "Open...", "Save","Save As","","Exit" };
		Boolean[] itemVisible = new Boolean[] { true, true, true }; 
		JMenu fileMenu = createMenu("File", fileItems);
		//use "" for separator
		String[] editItems = new String[] { "Cut", "Copy", "Paste", "", "Additive Cut", "Additive Copy",
				"","Find & Replace..." };  //  ,"","Date Time"
		JMenu editMenu = createMenu("Edit", editItems);
		
		//help menu
		String[] helpItems = new String[] {"Help topics","About Collaborative TextEditor"};
		JMenu helpMenu = createMenu("Help", helpItems);
		
		JMenu macroMenu = createDynamicMacroMenu();

		JMenuBar bar = new JMenuBar();
		bar.add(fileMenu);
		bar.add(editMenu);
		bar.add(macroMenu);
		bar.add(helpMenu);
		
		setJMenuBar(bar);
	}

	/**
	 * Manually created Macros menu
	 * @return JMenu of dynamically changed manually created Macros menu items
	 */
	private JMenu createDynamicMacroMenu() {
		JMenu macroMenu = new JMenu("Macros");
		
		recordMacro = new JMenuItem("Record Macro");
		recordMacro.addActionListener(this);
		macroMenu.add(recordMacro);
		
		stopMacro = new JMenuItem("Stop recording");
		stopMacro.addActionListener(this);
		stopMacro.setVisible(false);
		macroMenu.add(stopMacro);
		
		JSeparator separator = new JSeparator();
		macroMenu.add(separator);
		
		playMacro = new JMenuItem("Play Macro");
		playMacro.addActionListener(this);
		playMacro.setEnabled(false);
		macroMenu.add(playMacro);
		return macroMenu;
	}

	// for button search invoked.
	private void searchOperation(String pattern) {
		// TODO Auto-generated method stub
		int index = 0;
		textArea.requestFocusInWindow();
		
		String contents = textArea.getText();
		if (contents == null ) return;
		pattern = pattern.toLowerCase();
		contents = contents.toLowerCase();
		
		index = contents.indexOf(pattern, head);		
		if (index != -1){
			
			textArea.select(index, index + pattern.length());
			head = index + 1;
		}
		else {
			head = 0;
			
			JOptionPane.showMessageDialog(textArea,pattern +" is not find!"  ,"Information",JOptionPane.INFORMATION_MESSAGE);
		}
	}
	
	/**
	 * Creates a toolbar with additional options
	 */
	private void addToolbar() {
		getContentPane().add(toolBar, BorderLayout.NORTH);
		toolBar.add(textField);
		textField.setColumns(10);
		
		
		JButton btnSearch = new JButton("Search");
		btnSearch.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				searchOperation(textField.getText());
			}			
		});
		toolBar.add(btnSearch);
		
		JSeparator separator_1 = new JSeparator();
		toolBar.add(separator_1);
		
		JButton btnSpellCheck = new JButton("Spell check");
		btnSpellCheck.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				
		 		JOptionPane.showMessageDialog (textArea, "Current Function is disabled.", "Information", 
						JOptionPane.INFORMATION_MESSAGE);
		 		

			}
		});
		toolBar.add(btnSpellCheck);
	}

	/**
	 * Creates a main working text area with auxiliary tools, such as scrollbar, font parameters
	 */
	private void addTextArea() {
		textArea = new JTextArea();
		textArea.setWrapStyleWord(true);
		textArea.setLineWrap(true);
		textArea.setSelectedTextColor(Color.BLUE);

		textArea.getDocument().addDocumentListener(this);
		//jie add keylisten to textArea
		textArea.addKeyListener(this);
		//Font(String name, int style, int size) 
		Font defaultFont = new Font("Verdana",Font.PLAIN,16);
		textArea.setFont(defaultFont);
		textArea.requestFocusInWindow();
	
		
		//@ZHYJ.
		JScrollPane scrollerpane = new JScrollPane(textArea);
		scrollerpane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
		getContentPane().add(scrollerpane, BorderLayout.CENTER);
	}

	/**
	 * Creates a status bar
	 */
	private void addStatusBar() {
		infoStatus = new JLabel("  System Info: Help F1");
		getContentPane().add(infoStatus, BorderLayout.SOUTH);
	}
	
	/**
	 * Menu creator with static items.
	 * @param menuName name of the menu group
	 * @param items is an array of menu item names
	 * @return JMenu instance to connect to menu bar. 
	 */
	protected JMenu createMenu(String menuName, String[] items) {
		
		JMenu groupMenu = new JMenu(menuName);
		
		for (int i = 0; i < items.length; i++){
			if (items[i] == ""){
				JSeparator separator = new JSeparator();
				groupMenu.add(separator);
			}
			else{
				JMenuItem item = new JMenuItem(items[i]);
				item.addActionListener(this);
				groupMenu.add(item);
			}
		}

		return groupMenu;
	}

	/**
	 * Menu exit or close window action.
	 */
	private void exitWindowAction(){
		FileOperation fops = new FileOperation(this);
		if (fops.checkSaveFile() != DISCARDFILE){ 
			textArea.removeKeyListener(this);
			System.exit(0);			
		}
		return;
	} 
	/**
	 * Action performer. Assigns an action depending on action name
	 */
	public void actionPerformed(ActionEvent e){
		
		String menuString = e.getActionCommand();
		  
		if (menuString.equals("New")){
			//@ZHYJ:
			new FileOperation(this).createNewFile();
		}
			
		else if (menuString.equals("Open...")){
			//@ZHYJ: 
			new FileOperation(this).openFile();
		}
		else if (menuString.equals("Save")){
			//@ZHYJ:  
			new FileOperation(this).fileSave(false);
		}
		
		else if(menuString.equals("Save As")){
			//@ZHYJ
			new FileOperation(this).fileSave(true);
		}
		
		else if (menuString.equals("Exit")){
			//@ZHYJ:  
			exitWindowAction();
		}
		
		else if(menuString.equals("Find & Replace...")){			
			FindAndReplace findReplaceDialog = new FindAndReplace(this.textArea);
		}
		
		
	
		else if (menuString.equals("Record Macro")){
			recordMacro.setVisible(false);
			stopMacro.setVisible(true);
			playMacro.setEnabled(false);
			//jie initial the macro object
			this.macroItem.getMacrosteps().clear();
			this.macroItem.setStopFlag(false);
			
		}
		else if (menuString.equals("Stop recording")){
			recordMacro.setVisible(true);
			stopMacro.setVisible(false);
			playMacro.setEnabled(true);
			//jie add flag indicating stop
			macroItem.setStopFlag(true);
		}
		else if (menuString.equals("Play Macro")){
			//jie call play macro
			textArea.setFocusable(true);
			macroItem.playMacro();
		}
		else if (menuString.equals("Help topics")){
			
			textArea.requestFocusInWindow();
			JOptionPane.showMessageDialog(this, "Current without Content", "Help topic", JOptionPane.INFORMATION_MESSAGE);
			
		}
		else if (menuString.equals("About Collaborative TextEditor")){
			
			textArea.requestFocusInWindow();
			JOptionPane.showMessageDialog(this, 
					"\n   Concordia University  SOEN 6441 Project" +
					"\n          Collaborative TextEditor        \n" +
					"\n   Team member: " +
					"\n\n\n\n\n\n\n"+
					"\n        Version 1.0          Summer 2011.",
					"Collaborative TextEditor", JOptionPane.INFORMATION_MESSAGE);
			
		}
		else{
			try {
				new FileKeeper().getOperation(textArea, menuString, infoStatus);
			} catch (Exception ex) {
				infoStatus.setText(ex.getMessage());
			}
		}
			
	}
	/**Sets the flag whether the file is new*/
	public void setNewFile(boolean isNewFile) {
		this.isNewFile = isNewFile;
	}
	/**
	 * 
	 */
	public boolean isNewFile() {
		return isNewFile;
	}
	/**
	 * 
	 */
	public void setCurrentFile(File currentFile) {
		this.currentFile = currentFile;
	}
	/**
	 * 
	 */
	public File getCurrentFile() {
		return currentFile;
	}
	/**
	 * 
	 */
	public void setModified(boolean isModified) {
		this.isModified = isModified;
	}
	/**
	 * 
	 */
	public boolean isModified() {
		return isModified;
	}
	/**
	 * Class defining program hotkeys
	 */
	class HotKeyMap {
		
		public void makeHotKeyMap() {
			InputMap inMap = new InputMap();
			
			KeyStroke EnterKs = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
			KeyStroke CtrlcKs = KeyStroke.getKeyStroke("control C");
			KeyStroke CtrlvKs = KeyStroke.getKeyStroke("contol V");
			KeyStroke TabKs = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0);
			KeyStroke CapsKs = KeyStroke.getKeyStroke(KeyEvent.VK_CAPS_LOCK, 0);
			
			inMap.put(EnterKs, "entKs");
			inMap.put(CtrlcKs, "ctrlc");
			inMap.put(CtrlvKs, "ctrlv");
			inMap.put(TabKs, "tabKs");
			inMap.put(CapsKs, "capsKs");
			
			textArea.setInputMap(JComponent.WHEN_FOCUSED, inMap);
	
		}
	}
	/**
	 * 
	 */
	@Override
	public void changedUpdate(DocumentEvent arg0) {
		setModified(true);
	}
	/**
	 * 
	 */
	@Override
	public void insertUpdate(DocumentEvent arg0) {
		setModified(true);
	}
	/**
	 * 
	 */
	@Override
	public void removeUpdate(DocumentEvent arg0) {
		setModified(true);
		
	}

	@Override
	public void keyPressed(KeyEvent e) {
		// jie
		
	}

	@Override
	public void keyReleased(KeyEvent e) {
		// jie
		macroItem.recordMacro(e);
	}

	@Override
	public void keyTyped(KeyEvent e) {
		// Jie
		
	} 
}
